from django.conf import settings

from utilities.meta_view import (
    Response,
    APIViewList,
    APIViewUpdate,
    APIViewCreate,
    APIViewDestroy,
)
from models.vul import SystemKeywords, CustomKeywords, WhiteListKeywords
from apps.keyword.serializer import (
    KwdCountSchema,
    CustKeywordSchema,
    WhiteKeywordSchema,
    WhiteKeywordPostSchema,
    WhiteKeywordDelSchema,
)
from django.core.paginator import EmptyPage

from wass.display import LANGUAGE_CODE
from utilities.log import audit_log
from utilities.enums import AuditLogAction, LogModuleName, LogTypeName
from apps.strategy.display import KEYWORD_TYPE_NAME


class KwdCount(APIViewList):
    """关键词"""

    def list(self):
        """关键词列表"""
        if self.user_query:
            self.user_query['custom_id'] = self.user_query.pop('user_id', None)
        body = KwdCountSchema(**self.request.GET.dict()).dict(
            skip_defaults=True, by_alias=True
        )

        q = {}
        keyword = body.pop('keyword', None)
        if keyword:
            q = {'word': {'$regex': keyword}}

        s_agg = [
            {'$match': q},
            {
                '$group': {
                    '_id': '$type',
                    'type': {'$first': '$type'},
                    'sys_keyword': {'$sum': 1},
                }
            },
            {'$project': {'_id': 0}},
        ]
        c_agg = [
            {'$match': {**q, **self.user_query}},
            {
                '$group': {
                    '_id': '$type',
                    'type': {'$first': '$type'},
                    'cust_keyword': {'$sum': 1},
                }
            },
            {'$project': {'_id': 0}},
        ]

        resp = dict()
        for item in SystemKeywords.objects.aggregate(s_agg):
            resp.setdefault(item['type'], {}).update(item)

        for item in CustomKeywords.objects.aggregate(c_agg):
            resp.setdefault(item['type'], {}).update(item)

        resp = sorted(resp.values(), key=lambda x: x['type'], reverse=False)
        return Response(resp)


class KwdType(APIViewList, APIViewUpdate):
    """关键词"""

    def list(self):
        _type = self.kwargs['_type']
        # uid = self.request.data['user_id']
        if self.user_query:
            self.user_query['custom_id'] = self.user_query.pop('user_id', None)

        resp = {
            'system_keywords': list(
                SystemKeywords.objects.filter(type=_type).scalar('word')
            ),
            'custom_keywords': list(
                CustomKeywords.objects.filter(**self.user_query, type=_type).scalar('word')
            ),
        }
        return Response(resp)

    def update(self):
        """修改 每次修改前删除所有旧数据"""
        _type = self.kwargs['_type']
        uid = self.request.user.user_id

        body = CustKeywordSchema(**self.request.data).dict(
            skip_defaults=True, by_alias=True
        )

        words = [
            (CustomKeywords(word=word, type=_type, custom_id=uid))
            for word in body['cust_keywords']
        ]

        CustomKeywords.objects.filter(custom_id=uid, type=_type).delete()
        if words:
            CustomKeywords.objects.insert(words, load_bulk=False)

        log_data = {
            "module": LogModuleName.policy_management.value,
            "action": AuditLogAction.up.value,
            "type": LogTypeName.keyword.value,
            "desc": {"detail": f"设置自定义敏感词库类别'{KEYWORD_TYPE_NAME.get(LANGUAGE_CODE, {}).get(_type, 'unknown')}'"
                               f"为{body.get('cust_keywords', {})}。"},
        }
        audit_log(self.request, **log_data)
        return Response({'code': 0})


class WhiteKeyword(APIViewList, APIViewCreate, APIViewDestroy):
    """白名单 关键词"""

    def list(self):
        if self.user_query:
            self.user_query['custom_id'] = self.user_query.pop('user_id', None)

        data = WhiteKeywordSchema(**self.request.GET.dict()).dict()
        page, count = data['page'], data['count']

        q = {**self.user_query}
        word = data.get('word')
        if word:
            q['word__icontains'] = word

        all_pages = (
            WhiteListKeywords.objects.filter(**q)
            .order_by('-_id')
            .only('word')
            .paginate(count)
        )
        total = all_pages.count

        try:
            page_data = all_pages.page(page)
        except EmptyPage:
            page_data = []

        data = [{'_id': str(item.pk), 'word': item.word} for item in page_data]
        results = {'data': data, 'page': page, 'count': total}
        return Response({'code': 200, 'msg': 'ok', 'results': results})

    def create(self, *args, **kwargs):
        """新增白名单敏感词"""
        if self.user_query:
            self.user_query['custom_id'] = self.user_query.pop('user_id', None)

        data = WhiteKeywordPostSchema(**self.request.data).dict()
        white_keywords = data['white_keywords']

        exist_words = WhiteListKeywords.objects.filter(**self.user_query, word__in=white_keywords).scalar('word')
        words = [
            WhiteListKeywords(word=white_keyword, custom_id=self.request.user.user_id)
            for white_keyword in white_keywords
            if white_keyword not in exist_words
        ]
        if not words:  # 全是重复添加的
            return Response({'code': 0})
        WhiteListKeywords.objects.insert(words, load_bulk=False)
        log_data = {
            "module": LogModuleName.policy_management.value,
            "action": AuditLogAction.create.value,
            "type": LogTypeName.keyword.value,
            "desc": {"detail": "新增敏感词白名单"},
        }
        audit_log(self.request, **log_data)
        return Response({'code': 0})

    def destroy(self):
        if self.user_query:
            self.user_query['custom_id'] = self.user_query.pop('user_id', None)

        data = WhiteKeywordDelSchema(**self.request.data).dict()
        wk_ids = data['whitekey_ids']
        WhiteListKeywords.objects.filter(**self.user_query, pk__in=wk_ids).delete()

        log_data = {
            "module": LogModuleName.policy_management.value,
            "action": AuditLogAction.del_.value,
            "type": LogTypeName.keyword.value,
            "desc": {"detail": "删除敏感词白名单"},
        }
        audit_log(self.request, **log_data)

        return Response({'code': 0})
